package timbap.visualizer.coreplugins;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import processing.core.PApplet;
import processing.core.PImage;
import timbap.visualizer.api.context.PluginContext;
import timbap.visualizer.api.context.recorditems.RecordItemManager;
import timbap.visualizer.api.model.MsPinkyTimeCode;
import timbap.visualizer.api.model.RecordItem;
import timbap.visualizer.api.model.TimeCode;
import timbap.visualizer.api.model.Transformation;
import timbap.visualizer.api.plugin.recorditems.AbstractSelectedRecordItemPlugin;
import timbap.visualizer.coreplugins.lib.playingrecorditem.EmptyPlaylistManagerImpl;
import timbap.visualizer.coreplugins.lib.playingrecorditem.EmptyRecordItemManagerImpl;

import java.util.Date;

public class DefaultPlayingRecordItemPlugin extends AbstractSelectedRecordItemPlugin {

    private static final Log LOG = LogFactory.getLog(DefaultPlayingRecordItemPlugin.class);
    
	private static final int PLAYBACK_RETURN_HINT_WIDTH_EXPONENT = 16;
	
	private DefaultBrowsingModeControlImpl returnHintBrowsingModeControl;
	private TimeCode returnHintTimeCode;

    @Override
    public void init(PluginContext pPluginContext) {
        super.init(pPluginContext);
        EmptyPlaylistManagerImpl tEmptyPlaylistManager = new EmptyPlaylistManagerImpl(getContext().getCfg().getItemCount());
		RecordItemManager tRecordItemManager = new EmptyRecordItemManagerImpl(getContext().getCfg().getItemCount());
		tRecordItemManager.initializeRecordItems(tEmptyPlaylistManager);
		returnHintBrowsingModeControl = new DefaultBrowsingModeControlImpl();
        PluginContext tHintContext = getContext().cloneContext();
        tHintContext.setPlaylistManager(tEmptyPlaylistManager);
        tHintContext.setRecordItemManager(tRecordItemManager);
        returnHintBrowsingModeControl.init(tHintContext);
        returnHintTimeCode = new MsPinkyTimeCode();
    }

	public void drawRecordItem(RecordItem pRecordItem) {
        
		getContext().getP5Applet().pushMatrix();
        applyRecordItemTrafo(pRecordItem, getContext().getCfg().getScreenHeight() / 400f);
		
    	PImage tTextureImage = 
    		getContext().getTextureCacheManager().getArtworkTextureAsync(pRecordItem.getPlaylistEntry());
        if (tTextureImage != null) {
            getContext().getP5Applet().beginShape();
            getContext().getP5Applet().tint(pRecordItem.getTransformation().getAlphaValue() * 255);
            getContext().getP5Applet().image(tTextureImage, -50, -50, 100, 100);
            getContext().getP5Applet().endShape();
        }
        
        drawPlaybackReturnHint(pRecordItem);
        
        getContext().getP5Applet().popMatrix();
        
    }
	
	
	protected void applyRecordItemTrafo(RecordItem pRecordItem, float pScaleFactor) {
    	
    	Transformation tRecordItemTrafo = pRecordItem.getTransformation();
        
    	getContext().getP5Applet().translate(tRecordItemTrafo.getXTranslation(),
    							             tRecordItemTrafo.getYTranslation(),
    							             tRecordItemTrafo.getZTranslation());
    	getContext().getP5Applet().scale(tRecordItemTrafo.getScaleFactor() * pScaleFactor);
    	getContext().getP5Applet().rotate(tRecordItemTrafo.getRotation());
    	getContext().getP5Applet().rotateX(tRecordItemTrafo.getXRotation());
        
    }
	
	private void drawPlaybackReturnHint(RecordItem pRecordItem) {
        
        float tRotation = pRecordItem.getTransformation().getRotation();
        float tMappedRotation = PApplet.map(PApplet.abs(tRotation), 0, PApplet.PI, 1, 0);
        
        float tAlphaValue = 255 * PApplet.pow(tMappedRotation,PLAYBACK_RETURN_HINT_WIDTH_EXPONENT);
        if (tAlphaValue > 1) {
            getContext().getP5Applet().translate(0,-60,1);
            getContext().getP5Applet().fill(0,0,0, tAlphaValue);

            getContext().getP5Applet().ellipse(0,0,25,50);
            getContext().getP5Applet().translate(0,0,-2);
            getContext().getP5Applet().ellipse(0,0,25,50);

            float tHintItemsAlphaValue = (tAlphaValue > 100) ? 255 : 0;
            if (tHintItemsAlphaValue > 0) {
                getContext().getP5Applet().fill(255,255,255, tHintItemsAlphaValue);

                returnHintTimeCode.setAbsolutePosition(
                        new Date().getTime() * 10 % (int)returnHintTimeCode.getMaximumAbsolutePosition());
                returnHintTimeCode.setVelocity(1.0f);
                returnHintTimeCode.setSignalPower(1.0f);
                returnHintBrowsingModeControl.timeCodeUpdated(returnHintTimeCode);

                for (RecordItem tRecordItem: returnHintBrowsingModeControl.getContext().getRecordItemManager().getRecordItems()) {

                    getContext().getP5Applet().pushMatrix();
                    getContext().getP5Applet().translate(0,20,5);

                    Transformation tItemTrafo = tRecordItem.getTransformation();
                    getContext().getP5Applet().translate(tItemTrafo.getXTranslation() * 0.04f,
                                                         tItemTrafo.getYTranslation() * 0.04f);
                    getContext().getP5Applet().scale(tItemTrafo.getScaleFactor());

                    getContext().getP5Applet().ellipse(0, 0, 4, 4);
                    getContext().getP5Applet().translate(0,0,-10);
                    getContext().getP5Applet().ellipse(0, 0, 4, 4);

                    getContext().getP5Applet().popMatrix();

                }
            }
            getContext().getP5Applet().fill(255,255,255);
        }
    }

}
